package csu.web.credit_bank.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import csu.web.credit_bank.mapper.CoursesMapper;
import csu.web.credit_bank.mapper.StudentViewedResourceMapper;
import csu.web.credit_bank.pojo.*;
import csu.web.credit_bank.pojo.vo.SelectedCourseVO;
import csu.web.credit_bank.service.*;
import csu.web.credit_bank.utils.AliOssUtil;
import csu.web.credit_bank.utils.UUIDManager;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CoursesServiceImpl extends ServiceImpl<CoursesMapper, Course> implements CoursesService {

    @Autowired
    private UUIDManager uuidManager;

    @Autowired
    private CourseResourcesService courseResourcesService;

    @Autowired
    private CourseSelectionsService courseSelectionsService;

    @Autowired
    private LearningProgressService learningProgressService;

    @Autowired
    private UsersService usersService; //

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private AliOssUtil aliOssUtil;

    @Autowired
    private CoursesMapper coursesMapper;

    @Autowired
    private TeachersService teachersService; // 【新增】注入 TeachersService

    @Autowired
    private StudentViewedResourceMapper studentViewedResourceMapper;


    @Override
    public Course createCourse(Course course) {
        String courseId = uuidManager.getUUID();
        if (courseId == null) {
            throw new RuntimeException("ID池已空，无法创建新课程.");
        }
        course.setId(courseId);
        this.save(course);
        return course;
    }

    @Override
    public Course updateCourse(Course course) {
        boolean success = this.updateById(course);
        if (success) {
            return this.getById(course.getId());
        }
        return null;
    }

    @Override
    @Transactional
    public boolean deleteCourse(String id) {
        QueryWrapper<CourseResource> resourceWrapper = new QueryWrapper<>();
        resourceWrapper.eq("course_id", id);
        courseResourcesService.remove(resourceWrapper);

        QueryWrapper<CourseSelection> selectionWrapper = new QueryWrapper<>();
        selectionWrapper.eq("course_id", id);
        courseSelectionsService.remove(selectionWrapper);

        return this.removeById(id);
    }

    @Override
    @Transactional
    public Course createCourseWithImage(Course course, MultipartFile imageFile) {
        if (imageFile != null && !imageFile.isEmpty()) {
            try {
                String imageUrl = aliOssUtil.upload(imageFile.getInputStream(), imageFile.getOriginalFilename());
                if (StringUtils.hasText(imageUrl)) {
                    course.setImage(imageUrl);
                }
            } catch (Exception e) {
                throw new RuntimeException("封面图片上传失败", e);
            }
        }
        return this.createCourse(course);
    }

    @Override
    public IPage<Course> listCoursesByTeacherId(String teacherId, int pageNum, int pageSize) {
        Page<Course> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(teacherId)) {
            queryWrapper.eq("teacher_id", teacherId);
        }
        return this.baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public IPage<SelectedCourseVO> getSelectedCoursesByUserId(String userId, int pageNum, int pageSize) {
        Page<SelectedCourseVO> page = new Page<>(pageNum, pageSize);
        return this.baseMapper.selectSelectedCoursesByUserId(page, userId);
    }

    @Override
    public List<Resource> getResourcesByCourseId(String courseId) {
        QueryWrapper<CourseResource> resourceLinkWrapper = new QueryWrapper<>();
        resourceLinkWrapper.eq("course_id", courseId);
        List<CourseResource> courseResources = courseResourcesService.list(resourceLinkWrapper);

        if (courseResources.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> resourceIds = courseResources.stream()
                .map(CourseResource::getResourceId)
                .collect(Collectors.toList());
        QueryWrapper<Resource> resourceDetailWrapper = new QueryWrapper<>();
        resourceDetailWrapper.in("id", resourceIds);

        return resourceService.list(resourceDetailWrapper);
    }

    @Override
    public IPage<Course> searchCourses(int pageNum, int pageSize, String q) {
        Page<Course> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        if (q != null && !q.trim().isEmpty()) {
            queryWrapper.and(wrapper ->
                    wrapper.like("name", q)
                            .or()
                            .like("description", q)
            );
        }
        return this.baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public IPage<Course> searchCourses(int pageNum, int pageSize, String q, String sortBy) {
        Page<Course> page = new Page<>(pageNum, pageSize);
        return this.baseMapper.searchCourses(page, q, sortBy);
    }

    @Override
    public List<Map<String, Object>> getCombinedCourseResourcesWithChapter(String courseId) {
        QueryWrapper<CourseResource> resourceLinkWrapper = new QueryWrapper<>();
        resourceLinkWrapper.eq("course_id", courseId);
        List<CourseResource> courseResources = courseResourcesService.list(resourceLinkWrapper);

        if (courseResources.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> resourceIds = courseResources.stream()
                .map(CourseResource::getResourceId)
                .collect(Collectors.toList());

        QueryWrapper<Resource> resourceDetailWrapper = new QueryWrapper<>();
        resourceDetailWrapper.in("id", resourceIds);
        List<Resource> resources = resourceService.list(resourceDetailWrapper);

        Map<String, Resource> resourceMap = resources.stream()
                .collect(Collectors.toMap(Resource::getId, Function.identity()));
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (CourseResource cr : courseResources) {
            Resource resourceDetail = resourceMap.get(cr.getResourceId());
            if (resourceDetail != null) {
                Map<String, Object> combined = new HashMap<>();
                combined.put("id", resourceDetail.getId());
                combined.put("title", resourceDetail.getTitle());
                combined.put("major", resourceDetail.getMajor());
                combined.put("category", resourceDetail.getCategory());
                combined.put("difficulty", resourceDetail.getDifficulty());
                combined.put("credit", resourceDetail.getCredit());
                combined.put("location", resourceDetail.getLocation());
                combined.put("coverImage", resourceDetail.getCoverImage());
                combined.put("publisherId", resourceDetail.getPublisherId());
                combined.put("chapter", cr.getChapter());
                resultList.add(combined);
            }
        }
        return resultList;
    }

    @Override
    @Transactional(readOnly = true)
    public IPage<Map<String, Object>> getSelectedCoursesWithProgress(String studentId, int page, int size) {
        Page<CourseSelection> selectionPageInfo = new Page<>(page, size);
        QueryWrapper<CourseSelection> selectionWrapper = new QueryWrapper<>();
        selectionWrapper.eq("user_id", studentId);
        IPage<CourseSelection> selectedCoursesPage = courseSelectionsService.page(selectionPageInfo, selectionWrapper);

        List<CourseSelection> selections = selectedCoursesPage.getRecords();
        if (selections.isEmpty()) {
            return new Page<Map<String, Object>>(page, size, selectedCoursesPage.getTotal()).setRecords(Collections.emptyList());
        }

        List<String> courseIds = selections.stream()
                .map(CourseSelection::getCourseId)
                .collect(Collectors.toList());

        List<Course> courses = this.listByIds(courseIds);
        Map<String, Course> courseMap = courses.stream()
                .collect(Collectors.toMap(Course::getId, Function.identity()));

        List<String> teacherIds = courses.stream()
                .map(Course::getTeacherId)
                .filter(StringUtils::hasText)
                .distinct()
                .collect(Collectors.toList());

        Map<String, User> userMap = new HashMap<>();
        if (!teacherIds.isEmpty()) {
            List<User> users = usersService.listByIds(teacherIds); //
            userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity())); //
        }

        Map<String, Teachers> teacherInfoMap = new HashMap<>();
        if (!teacherIds.isEmpty()) {
            List<Teachers> teachers = teachersService.listByIds(teacherIds); // 【新增】查询 Teachers 表
            teacherInfoMap = teachers.stream().collect(Collectors.toMap(Teachers::getUserId, Function.identity())); //
        }

        QueryWrapper<LearningProgress> progressWrapper = new QueryWrapper<>();
        progressWrapper.eq("student_id", studentId).in("course_id", courseIds);
        List<LearningProgress> progresses = learningProgressService.list(progressWrapper);
        Map<String, BigDecimal> progressMap = progresses.stream()
                .collect(Collectors.toMap(LearningProgress::getCourseId, LearningProgress::getProgressPercent, (p1, p2) -> p1));


        QueryWrapper<StudentViewedResource> viewedResourceWrapper = new QueryWrapper<>();
        viewedResourceWrapper.eq("student_id", studentId).in("course_id", courseIds);
        List<StudentViewedResource> allViewedResources = studentViewedResourceMapper.selectList(viewedResourceWrapper);

        Map<String, StudentViewedResource> lastViewedByCourse = allViewedResources.stream()
                .collect(Collectors.toMap(
                        StudentViewedResource::getCourseId,
                        v -> v,
                        (existing, replacement) -> existing.getViewTime().after(replacement.getViewTime()) ? existing : replacement
                ));

        Set<String> lastViewedResourceIds = lastViewedByCourse.values().stream()
                .map(StudentViewedResource::getResourceId)
                .collect(Collectors.toSet());


        Map<String, String> resourceTitleMap = new HashMap<>();
        if (!lastViewedResourceIds.isEmpty()) {
            List<Resource> lastViewedResources = resourceService.listByIds(lastViewedResourceIds);
            resourceTitleMap = lastViewedResources.stream()
                    .collect(Collectors.toMap(Resource::getId, Resource::getTitle));
        }

        // 将所有信息组合成前端需要的格式
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (CourseSelection selection : selections) {
            Course course = courseMap.get(selection.getCourseId());
            if (course != null) {
                Map<String, Object> courseData = new HashMap<>();
                courseData.put("id", course.getId());
                courseData.put("name", course.getName());
                courseData.put("image", course.getImage());

                //返回学分 credit
                courseData.put("credit", course.getCredit());

                // 获取教师信息（用户名和头像）
                User user = userMap.get(course.getTeacherId()); //
                Teachers teacherInfo = teacherInfoMap.get(course.getTeacherId()); //

                if (user != null) {
                    courseData.put("teacherName", user.getUsername()); //
                } else {
                    courseData.put("teacherName", "未知教师");
                }
                if (teacherInfo != null) {
                    courseData.put("teacherAvatar", teacherInfo.getAvatar()); // 【新增】添加教师头像
                } else {
                    courseData.put("teacherAvatar", null); // 或者设置一个默认头像URL
                }

                BigDecimal progressPercent = progressMap.getOrDefault(course.getId(), BigDecimal.ZERO);
                courseData.put("progress_percent", progressPercent);

                StudentViewedResource lastView = lastViewedByCourse.get(course.getId());
                String lastStudy = "未知";
                if (lastView != null) {
                    lastStudy = resourceTitleMap.getOrDefault(lastView.getResourceId(), "无");
                }
                courseData.put("last_study", lastStudy);

                resultList.add(courseData);
            }
        }

        // 构建并返回最终的分页结果对象
        Page<Map<String, Object>> resultPage = new Page<>(page, size, selectedCoursesPage.getTotal());
        resultPage.setRecords(resultList);

        return resultPage;
    }

    @Override
    public IPage<Course> searchCourses(int pageNum, int pageSize, String q, String sortBy, String teacherId) {
        Page<Course> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        if (q != null && !q.trim().isEmpty()) {
            queryWrapper.and(wrapper ->
                    wrapper.like("name", q)
                            .or()
                            .like("description", q)
            );
        }
        if (StringUtils.hasText(teacherId)) {
            queryWrapper.eq("teacher_id", teacherId);
        }
        if (StringUtils.hasText(sortBy)) {
            if ("creditDesc".equals(sortBy)) {
                queryWrapper.orderByDesc("credit");
            } else if ("creditAsc".equals(sortBy)) {
                queryWrapper.orderByAsc("credit");
            }
        }
        return this.baseMapper.selectPage(page, queryWrapper);
    }
}